iconv = require 'iconv-lite'
urlStr = 'http://s.etao.com/search?initiative_id=setao_20140319'
events = require 'events'
qs = require 'querystring'
url = require 'url'
http = require 'http'
fs = require 'fs'
events = (require 'events').EventEmitter
cheerio = require 'cheerio'
SeqQueue = require 'seq-queue'
queue = SeqQueue.createQueue(1000)
urlMap = {
    ymw:'http://list.yesmywine.com/z1',
    jx:'http://list.jiuxian.com/search.htm',
    yitao:'http://s.etao.com/search'
}
encodeURIComponent_GBK= (str)->
    if (str==null || typeof(str)=='undefined' || str=='') 
        return ''

    a = str.toString().split('')
    for i in [0..a.length-1]
        ai = a[i]
        if( (ai>='0' && ai<='9') || (ai>='A' && ai<='Z') || (ai>='a' && ai<='z') || ai is '.' || ai is '-' || ai is '_') 
            continue
        b = iconv.encode(ai, 'gbk')
        e = [''] # 注意先放个空字符串，最保证前面有一个%
        # e = []
        # for( j = 0; j<b.length; j++) 
        for j in [0..b.length-1]
            e.push( b.toString('hex', j, j+1).toUpperCase() )
        a[i] = e.join('%')

    return a.join('')

logEnd = (msg)->
    log?.map?={}
    now = new Date().getTime()
    log.map[msg]?= now 
    list = ('-' for num in [0..30])
    # console.log now
    tdif = (now-log.map[msg])/1000 + 'S'
    # list.concat list
    console.log (list.concat [msg],list,['[END]'],['[Time ',tdif,']']).join('')
    delete log.map[msg]

log = (msg)->
    # console.log log?.map
    log?.map?={}
    log.map[msg] = new Date().getTime()
    list = ('-' for num in [0..30])
    # list.concat list
    console.log (list.concat [msg],list,['[BEGIN]']).join('')


class Request extends events
    constructor:()->
        @u2 = null
        # @urlQueue = [] 
    request:(urlS,callback)=>
        # console.log urlString
        # if @urlQueue.length is 0 then return
            # urlS = @urlQueue.shift()
        if typeof urlS is 'string'
            urlObj = url.parse(urlS)
        else
            urlObj = urlS
        # console.log urlObj.protocol
        if urlObj.protocol == 'http:'
            protocolReq = http.request
            urlObj.port = 80
        else if urlObj.protocol == 'https:'
            protocolReq = https.request
            urlObj.port = 443
        # console.log protocolReq,urlObj
        # console.log urlS,urlObj
        urlObj.method ?= 'GET'
        if urlObj.postData 
            data = qs.stringify urlObj.postData
        if !callback
            callbck = ()->
                return
        log url.format urlS
        if urlObj.method.toLowerCase() is 'post'
            urlObj.headers = {  
                "Content-Type": 'application/x-www-form-urlencoded',  
                "Content-Length": data.length  
            } 
        req = protocolReq(urlObj, (res)=> 
            # @emit 'onFetchstart', url.parse(urlS),req
            # console.log("Got response: " + res.statusCode, res.headers)
            if(res.statusCode is 301 or res.statusCode is 302)
                @u2= res.headers.location
                if (@u2.indexOf 'http://') isnt 0 and (@u2.indexOf 'https://') isnt 0
                    @u2 = urlObj.protocol+'//'+ urlObj.host + decodeURIComponent(res.headers.location)
                console.log (JSON.stringify urlS )+ '  forword to  '+ @u2
                # @emit 'onFetchredirect' ,url.parse(urlS),@u2,res
                @request @u2,callback
            buffers = []
            size = 0
            # console.log c++
            res
            .on('data', (buffer)=> 
                buffers.push(buffer)
                size += buffer.length
            )
            .on('end', ()=> 
                logEnd url.format urlS
                responseBuffer = new Buffer size
                pos = 0;
                try
                    if buffers.length isnt 0
                        if !res.headers['content-type']
                            @charset = 'utf-8'
                        else
                            if (res.headers['content-type'].match /charset=(\w|\s|-|\d)*/)
                                @charset =  (res.headers['content-type'].match /charset=(\w|\s|-|\d)*/)[0].toLowerCase()
                                @charset = @charset.split('=')[1]
                            # @charset =  (res.headers['content-type'].match /charset=(\w|\s|-|\d)*/)[0].toLowerCase()
                            else 
                                @charset = 'gbk'

                            # @charset = @charset.split('=')[1]
                        # console.log 123213213213, @charset
                        for i in [0..buffers.length-1]
                            buffers[i].copy responseBuffer, pos
                            pos += buffers[i].length
                    # T.logEnd urlS
                        if res.statusCode is 200
                            if typeof urlS is 'string'
                                callback url.parse(urlS),responseBuffer,res 
                            else
                                callback urlS,responseBuffer,res
                catch e
                    console.log e
                    # errStr = JSON.stringify e
                    # throw new Error()

                # @emit 'onFetchComplete',url.parse(urlS),responseBuffer,res
            )

        )
        req.on('error', (e)=>
            # @emit 'onFetchclienterror',e
            console.log("Got error: " + e.message)
            # @request urlS,callback
            console.log urlS
            # throw e
            # request urlS,callback
        )
        if urlObj.method.toLowerCase() is 'post'
            # postStr = qs.stringify urlObj.postData
            # postStr = escape postStr
            req.write (qs.stringify urlObj.postData)
            delete urlObj.postData
        req.end()

# req = new Request()
class GetSearchItem extends events
    constructor:()->
        @delay = 15000;
        @req = new Request();
        # @siteArr = [{site:'也买酒',fun:@getYesMyWine},{site:'酒仙',fun:@getJiuXian},{site:'一淘',fun:@getYiTao}]
        @siteArr = [{site:'一淘',fun:@getYiTao}]
        @filePath = './data/rst.csv'
        if fs.existsSync(@filePath)  
            fs.unlinkSync(@filePath)
            title = '"'+['网站','关键词','标题','最低成交价','最高成交价','好评','评论数','出售','描述'].join('","')+'"\n'
            fs.writeFileSync(@filePath,title)
    getYiTao:(keyword,callback)=>
        q = {
            s:0,
            size:36
        }
        urlStr = urlMap.yitao+'?q='+ encodeURIComponent_GBK(keyword)+'&'+qs.stringify(q)
        console.log urlStr
        iter=(urlStr)=>
            @req.request urlStr,(urlObj,responseBuffer,res)=>
                str = iconv.decode responseBuffer,@req.charset
                $ = cheerio.load str
                isLast = false
                proList = $('div.main>div')
                proList.each (idx,item)=>
                    div = $(item).find('div.info-panel')
                    title = div.find('a').attr('title')
                    price = $(item).find('span.price').text()
                    sales = $(item).find('div.sales-volume').text()
                    if title is undefined 
                        isLast = true
                    else
                        cnt = '"'+['一淘',keyword,title,price,'','','',sales,''].join('","')+'"\n'
                        fs.appendFileSync @filePath,cnt
                q.s = (q.s+1)*q.size
                if isLast is false
                    urlStr = urlMap.yitao+'?q='+ encodeURIComponent_GBK(keyword)+'&'+qs.stringify(q)
                    setTimeout (()->
                        iter(urlStr)
                        ),@delay
                else 
                    @emit 'end','一淘网'
                    if callback then callback()
        iter(urlStr)
    getJiuXian:(keyword,callback)=>
        param = {keys:keyword}
        urlStr = [urlMap.jx ,'?', qs.stringify(param)].join('')
        console.log urlStr
        iter = (urlStr)=>
            @req.request urlStr,(urlObj,responseBuffer,res)=>
                str = iconv.decode responseBuffer,@req.charset
                $ = cheerio.load str
                liList = $('div.pro_list>ul>li')
                idList = []
                map = {}
                liList.each (idx,item)=>
                    li = $(item)
                    title = li.find('div.pro_list_ad').text().trim()
                    div = li.find('div.pro_list_price')
                    id = div.attr('id').match(/\d+/)[0]
                    desc = li.find('div.pro_list_com').text().replace(/\s/g,'').trim()
                    ss = li.find('div.pro_list_com').text().replace(/\s/g,'').trim()
                    [s1,s2] = ss.split('已有')
                    map[id] = {
                        title:title,
                        s1:s1,
                        s2:s2
                    }
                    # console.log s1,s2
                    # li.find('div.pro_list_price')
                    idList.push(id)
                    # m.log div.attr('id').match(/\d+/)[0]
                _urlStr = 'http://list.jiuxian.com/httpProxyAccess.htm?t='+ new Date().getTime()
                urlObj = url.parse(_urlStr)
                urlObj.method = 'post'
                _param = {
                    target:'http://act.jiuxian.com/act/selectPricebypids.htm',
                    ids:idList.join(',')
                    }
                urlObj.postData = _param
                # console.log qs.stringify(urlObj.postData)
                @req.request urlObj,(_urlObj,_responseBuffer,_res)=>
                    str = iconv.decode _responseBuffer,@req.charset
                    json = JSON.parse(str)
                    for i of map 
                        np = json.data[i].np
                        mp = json.data[i].mp
                        map[i].maxPrice = '￥'+mp
                        map[i].minPrice = '￥'+np
                        content = '"'+['也买网',keyword,map[i].title,map[i].minPrice,map[i].maxPrice,map[i].s1,map[i].s2,'',''].join('","')+'"\n'
                        fs.appendFileSync @filePath,content
                        # console.log map[i]
                    next = $('#curp').next('a')
                    if next.text() isnt '下一页'
                        path = next.attr('href')
                        _str = _urlObj.protocol + '//'+ _urlObj.host + path
                        setTimeout (()->
                            iter(_str)
                        ),@delay
                    else 
                        @emit 'end','酒仙网'
                        if callback then callback()
                    # if callback then callback()

                    # console.log json.data[i]
                    # console.log map
        iter(urlStr)
    getYesMyWine:(keyword,callback)=>
        param = {q:keyword}
        # console.log urlMap.ymw,param
        urlStr = urlMap.ymw+'?'+qs.stringify(param)
        console.log urlStr
        iter = (urlStr)=>
            @req.request urlStr,(urlObj,responseBuffer,res)=>
                str = iconv.decode responseBuffer,@req.charset
                $ = cheerio.load str
                $('ul.piclist>li').each (idx,item)=>
                    li = $(item)
                    dd = li.find('dl>dd.base')
                    a1 = dd.find('>a').attr('title').replace(/\s/g,'').trim()
                    s1 = dd.find('span.en').text().trim()
                    s2 = dd.find('span.promo').text().trim()
                    #描<div></div>述
                    desc = a1+s1+s2
                    #最低价格、最高价格
                    minPrice = dd.find('span.minprice').text().trim()
                    maxPrice = dd.find('span.maxprice').text().trim()
                    ddSum = li.find('dl>dd.sum')
                    #好评度
                    ratecount = ddSum.find('span.ratecount').text().trim()
                    #评论
                    cmt = ddSum.find('span.commentcount').text().trim()
                    #售出
                    soldnum = ddSum.find('span.soldnum').text().trim()
                    ddInfo = li.find('dd.info')
                    info = ddInfo.text().replace(/\s/g,'').trim()
                    content = '"'+['酒仙网',keyword,desc,minPrice,maxPrice,ratecount,cmt,soldnum,info].join('","')+'"\n'
                    # console.log @filePath
                    fs.appendFileSync @filePath,content
                    # console.log desc,minPrice,maxPrice,ratecount,cmt,soldnum,info
                aElem = $('div.page>a.next:contains(下一页)')
                if aElem.length > 0 
                    next = aElem.attr('href')
                    next = 'http://'+urlObj.host+ next 
                    setTimeout (()->
                        console.log 'next',next
                        iter(next)
                        ),@delay
                else
                    @emit 'end','也买酒'
                    if callback then callback()
                # console.log info
        iter(urlStr)

run = ()->
    winePath = './data/wine.list'
    wineStr = (fs.readFileSync winePath).toString()
    wineList = wineStr.split('\n')
    gst = new GetSearchItem()
    ct = 0
    wineList.forEach (keyword)->
        for i in gst.siteArr
            queue.push((task)=>
                i.fun keyword,()=>
                    console.log i.site
                    task.done()
                )
        # queue.push((task)->
        #     gst.getJiuXian keyword,()->
        #         console.log 'getJiuXian'
        #         task.done()
        #         )
        # queue.push((task)->
        #     gst.getYesMyWine keyword,()->
        #         console.log 'getYesMyWine'
        #         task.done()
        #         )
        # queue.push((task)->
        #     gst.getYiTao keyword,()->
        #         console.log 'getYesMyWine'
        #         task.done()
        #         )

        
    # urlStr = urlMap.soso+'?'+qs.stringify(param)
run()

test = ()->
    urlStr = 'http://list.yesmywine.com/z1-p2?q=%E5%B9%B2%E7%BA%A2&dts=L204.11#a_goods_top'
    # req.request urlStr,(urlObj,responseBuffer,res)->
    #     str = iconv.decode responseBuffer,req.charset
    #     console.log str
    gst = new GetSearchItem()
    # keyword = '拉芳罗榭庄园2008'
    keyword = '拉芳罗榭庄园2008(干红)'
    # gst.getJiuXian keyword,()->
    #     console.log '酒仙网',keyword
    # gst.getYesMyWine keyword,()->
    #     console.log '也买网',keyword
    gst.getYiTao keyword,()->
        console.log '一淘',keyword
    # gst.on 'end' ,(webSite)->
    #     console.log webSite
    # %C0%AD%B7%BC%C2%DE%E9%BF%D7%AF%D4%B02008%28%B8%C9%BA%EC%29
    # %C0%AD%B7%BC%C2%DE%E9%BF%D7%AF%D4%B02008%28%B8%C9%BA%EC%29
    # 
    # %C0%B7%C2%E9%D7%D42008%28%B8%BA%29
    console.log encodeURIComponent_GBK keyword
# test()







